home *** CD-ROM | disk | FTP | other *** search
/ Info-Mac 3 / Info_Mac_1994-01.iso / Development / General / GCC 1.37.1r15 / Machines / tm-news.h < prev    next >
Text File  |  1990-03-14  |  15KB  |  407 lines

  1. /* Definitions of target machine for GNU compiler.  SONY NEWS-OS 3.0 version.
  2.    Copyright (C) 1987, 1989 Free Software Foundation, Inc.
  3.  
  4. This file is part of GNU CC.
  5.  
  6. GNU CC is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 1, or (at your option)
  9. any later version.
  10.  
  11. GNU CC is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with GNU CC; see the file COPYING.  If not, write to
  18. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20. #ifndef USE_GAS
  21. /* This controls conditionals in tm-m68k.h.  */
  22. #define MOTOROLA
  23. #define SONY_ASM
  24. #endif
  25.  
  26. #include "tm-m68k.h"
  27.  
  28. /* See tm-m68k.h.  7 means 68020 with 68881.  */
  29.  
  30. #define TARGET_DEFAULT 7
  31.  
  32. /* Define __HAVE_68881__ in preprocessor, unless -msoft-float is specified.
  33.    This will control the use of inline 68881 insns in certain macros.  */
  34.  
  35. #define CPP_SPEC "%{!msoft-float:-D__HAVE_68881__}"
  36.  
  37. /* Names to predefine in the preprocessor for this target machine.  */
  38. /* These are the ones defined by Sony, plus mc68000 for uniformity with
  39.    GCC on other 68000 systems.  */
  40.  
  41. #ifdef news700
  42. #define CPP_PREDEFINES "-Dunix -Dbsd43 -Dsony -Dsony_news -Dmc68000 -Dmc68020 -Dnews700"
  43. #endif
  44. #ifdef news800
  45. #define CPP_PREDEFINES "-Dunix -Dbsd43 -Dsony -Dsony_news -Dmc68000 -Dmc68020 -Dnews800"
  46. #endif
  47. #ifdef news900
  48. #define CPP_PREDEFINES "-Dunix -Dbsd43 -Dsony -Dsony_news -Dmc68000 -Dmc68020 -Dnews900"
  49. #endif
  50. #ifdef news1500
  51. #define CPP_PREDEFINES "-Dunix -Dbsd43 -Dsony -Dsony_news -Dmc68000 -Dmc68020 -Dmc68030 -Dnews1500"
  52. #endif
  53. #ifdef news1700
  54. #define CPP_PREDEFINES "-Dunix -Dbsd43 -Dsony -Dsony_news -Dmc68000 -Dmc68020 -Dmc68030 -Dnews1700"
  55. #endif
  56. #ifdef news1800
  57. #define CPP_PREDEFINES "-Dunix -Dbsd43 -Dsony -Dsony_news -Dmc68000 -Dmc68020 -Dmc68030 -Dnews1800"
  58. #endif
  59. #ifdef news1900
  60. #define CPP_PREDEFINES "-Dunix -Dbsd43 -Dsony -Dsony_news -Dmc68000 -Dmc68020 -Dmc68030 -Dnews1900"
  61. #endif
  62.  
  63. /* This is BSD, so it wants DBX format.  */
  64.  
  65. #define DBX_DEBUGGING_INFO
  66.  
  67. /* Override parts of tm-m68k.h to fit Sony's assembler syntax.  */
  68.  
  69. #undef POINTER_BOUNDARY
  70. #undef BIGGEST_ALIGNMENT
  71. #undef CALL_USED_REGISTERS
  72. #undef FUNCTION_VALUE
  73. #undef LIBCALL_VALUE
  74. #undef FUNCTION_PROFILER
  75.  
  76. #ifdef MOTOROLA
  77. #undef FUNCTION_PROLOGUE
  78. #undef FUNCTION_EPILOGUE
  79. #undef REGISTER_NAMES
  80. #undef ASM_OUTPUT_REG_PUSH
  81. #undef ASM_OUTPUT_REG_POP
  82. #undef ASM_OUTPUT_DOUBLE
  83. #undef ASM_OUTPUT_SKIP
  84. #undef ASM_FORMAT_PRIVATE_NAME
  85. #undef PRINT_OPERAND
  86. #undef PRINT_OPERAND_ADDRESS
  87. #endif  
  88.  
  89. #undef ASM_OUTPUT_ALIGN
  90.  
  91. /* Allocation boundary (in *bits*) for storing pointers in memory.  */
  92. #define POINTER_BOUNDARY 32
  93.  
  94. /* There is no point aligning anything to a rounder boundary than this.  */
  95. #define BIGGEST_ALIGNMENT 32
  96.  
  97. /* A bitfield declared as `int' forces `int' alignment for the struct.  */
  98. #define PCC_BITFIELD_TYPE_MATTERS
  99.   
  100. /* NEWS makes d2, d3, fp2 and fp3 unsaved registers, unlike the Sun system.  */
  101.   
  102. #define CALL_USED_REGISTERS \
  103.  {1, 1, 1, 1, 0, 0, 0, 0, \
  104.   1, 1, 0, 0, 0, 0, 0, 1, \
  105.   1, 1, 1, 1, 0, 0, 0, 0}
  106.  
  107. /* NEWS returns floats and doubles in fp0, not d0/d1.  */
  108.  
  109. #define FUNCTION_VALUE(VALTYPE,FUNC) LIBCALL_VALUE (TYPE_MODE (VALTYPE))
  110.  
  111. #define LIBCALL_VALUE(MODE) \
  112.  gen_rtx (REG, (MODE), ((TARGET_68881 && ((MODE) == SFmode || (MODE) == DFmode)) ? 16 : 0))
  113.  
  114. #define ASM_OUTPUT_ALIGN(FILE,LOG)    \
  115.   fprintf (FILE, "\t.align %d\n", (LOG))
  116.  
  117. #ifdef MOTOROLA
  118.  
  119. /* Don't try to define `gcc_compiled.' since the assembler does not
  120.    accept symbols with periods.  This is no real loss since GDB only
  121.    really needs it for parms passed in registers.  */
  122. #define ASM_IDENTIFY_GCC(FILE)
  123.  
  124. #define FUNCTION_PROLOGUE(FILE, SIZE)     \
  125. { register int regno;                        \
  126.   register int mask = 0;                    \
  127.   extern char call_used_regs[];                    \
  128.   int fsize = ((SIZE) + 3) & -4;                \
  129.   if (frame_pointer_needed)                    \
  130.     { if (TARGET_68020 || fsize < 0x8000)            \
  131.         fprintf (FILE, "\tlink fp,#%d\n", -fsize);        \
  132.       else                            \
  133.     fprintf (FILE, "\tlink fp,#0\n\tsub.l #%d,sp\n", fsize); }  \
  134.   for (regno = 16; regno < FIRST_PSEUDO_REGISTER; regno++)    \
  135.     if (regs_ever_live[regno] && ! call_used_regs[regno])    \
  136.        mask |= 1 << (regno - 16);                \
  137.   if (mask != 0)                        \
  138.     fprintf (FILE, "\tfmovem.x #0x%x,-(sp)\n", mask & 0xff);    \
  139.   mask = 0;                            \
  140.   for (regno = 0; regno < 16; regno++)                \
  141.     if (regs_ever_live[regno] && ! call_used_regs[regno])    \
  142.        mask |= 1 << (15 - regno);                \
  143.   if (frame_pointer_needed)                    \
  144.     mask &= ~ (1 << (15-FRAME_POINTER_REGNUM));            \
  145.   if (exact_log2 (mask) >= 0)                    \
  146.     fprintf (FILE, "\tmove.l %s,-(sp)\n", reg_names[15 - exact_log2 (mask)]);  \
  147.   else if (mask) fprintf (FILE, "\tmovem.l #0x%x,-(sp)\n", mask); }
  148.  
  149. #define FUNCTION_PROFILER(FILE, LABEL_NO) \
  150.    fprintf (FILE, "\tmove.l #LP%d,d0\n\tjsr mcount\n", (LABEL_NO));
  151.  
  152. #define FUNCTION_EPILOGUE(FILE, SIZE) \
  153. { register int regno;                        \
  154.   register int mask, fmask;                    \
  155.   register int nregs;                        \
  156.   int offset, foffset;                        \
  157.   extern char call_used_regs[];                    \
  158.   extern int current_function_pops_args;            \
  159.   extern int current_function_args_size;            \
  160.   int fsize = ((SIZE) + 3) & -4;                \
  161.   int big = 0;                            \
  162.   nregs = 0;  fmask = 0;                    \
  163.   for (regno = 16; regno < FIRST_PSEUDO_REGISTER; regno++)    \
  164.     if (regs_ever_live[regno] && ! call_used_regs[regno])    \
  165.       { nregs++; fmask |= 1 << (23 - regno); }            \
  166.   foffset = nregs * 12;                        \
  167.   nregs = 0;  mask = 0;                        \
  168.   if (frame_pointer_needed) regs_ever_live[FRAME_POINTER_REGNUM] = 0; \
  169.   for (regno = 0; regno < 16; regno++)                \
  170.     if (regs_ever_live[regno] && ! call_used_regs[regno])    \
  171.       { nregs++; mask |= 1 << regno; }                \
  172.   offset = foffset + nregs * 4;                    \
  173.   if (offset + fsize >= 0x8000                     \
  174.       && frame_pointer_needed                    \
  175.       && (mask || fmask))                    \
  176.     { fprintf (FILE, "\tmove.l #%d,a0\n", -fsize);        \
  177.       fsize = 0, big = 1; }                    \
  178.   if (exact_log2 (mask) >= 0) {                    \
  179.     if (big)                            \
  180.       fprintf (FILE, "\tmove.l (-%d,fp,a0.l),%s\n",        \
  181.            offset + fsize, reg_names[exact_log2 (mask)]);    \
  182.     else if (! frame_pointer_needed)                \
  183.       fprintf (FILE, "\tmove.l (sp)+,%s\n",            \
  184.            reg_names[exact_log2 (mask)]);            \
  185.     else                            \
  186.       fprintf (FILE, "\tmove.l (-%d,fp),%s\n",            \
  187.            offset + fsize, reg_names[exact_log2 (mask)]); }    \
  188.   else if (mask) {                        \
  189.     if (big)                            \
  190.       fprintf (FILE, "\tmovem.l (-%d,fp,a0.l),#0x%x\n",        \
  191.            offset + fsize, mask);                \
  192.     else if (! frame_pointer_needed)                \
  193.       fprintf (FILE, "\tmovem.l (sp)+,#0x%x\n", mask);        \
  194.     else                            \
  195.       fprintf (FILE, "\tmovem.l (-%d,fp),#0x%x\n",        \
  196.            offset + fsize, mask); }                \
  197.   if (fmask) {                            \
  198.     if (big)                            \
  199.       fprintf (FILE, "\tfmovem.x (-%d,fp,a0.l),#0x%x\n",    \
  200.            foffset + fsize, fmask);                \
  201.     else if (! frame_pointer_needed)                \
  202.       fprintf (FILE, "\tfmovem.x (sp)+,#0x%x\n", fmask);    \
  203.     else                            \
  204.       fprintf (FILE, "\tfmovem.x (-%d,fp),#0x%x\n",        \
  205.            foffset + fsize, fmask); }            \
  206.   if (frame_pointer_needed)                    \
  207.     fprintf (FILE, "\tunlk fp\n");                \
  208.   if (current_function_pops_args && current_function_args_size)    \
  209.     fprintf (FILE, "\trtd #%d\n", current_function_args_size);    \
  210.   else fprintf (FILE, "\trts\n"); }
  211.  
  212. /* Difference from tm-m68k.h is in `fp' instead of `a6'.  */
  213.  
  214. #define REGISTER_NAMES \
  215. {"d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",    \
  216.  "a0", "a1", "a2", "a3", "a4", "a5", "fp", "sp",    \
  217.  "fp0", "fp1", "fp2", "fp3", "fp4", "fp5", "fp6", "fp7"}
  218.  
  219. /* This is how to output an insn to push a register on the stack.
  220.    It need not be very fast code.  */
  221.  
  222. #define ASM_OUTPUT_REG_PUSH(FILE,REGNO)  \
  223.   fprintf (FILE, "\tmove.l %s,-(sp)\n", reg_names[REGNO])
  224.  
  225. /* This is how to output an insn to pop a register from the stack.
  226.    It need not be very fast code.  */
  227.  
  228. #define ASM_OUTPUT_REG_POP(FILE,REGNO)  \
  229.   fprintf (FILE, "\tmove.l (sp)+,%s\n", reg_names[REGNO])
  230.   
  231. #define ASM_OUTPUT_DOUBLE(FILE,VALUE)  \
  232.   fprintf (FILE, "\t.double 0d%.20e\n", (VALUE))
  233.  
  234. #define ASM_OUTPUT_SKIP(FILE,SIZE)  \
  235.   fprintf (FILE, "\t.space %d\n", (SIZE))
  236.  
  237. /* Store in OUTPUT a string (made with alloca) containing
  238.    an assembler-name for a local static variable named NAME.
  239.    LABELNO is an integer which is different for each call.  */
  240.  
  241. #define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO)    \
  242. ( (OUTPUT) = (char *) alloca (strlen ((NAME)) + 13),    \
  243.   sprintf ((OUTPUT), "%s$$$%d", (NAME), (LABELNO)))
  244.  
  245. #define PRINT_OPERAND(FILE, X, CODE)  \
  246. { if (CODE == '.') fprintf (FILE, ".");                    \
  247.   else if (CODE == '#') fprintf (FILE, "#");                \
  248.   else if (CODE == '-') fprintf (FILE, "-(sp)");            \
  249.   else if (CODE == '+') fprintf (FILE, "(sp)+");            \
  250.   else if (CODE == '@') fprintf (FILE, "(sp)");                \
  251.   else if (CODE == '!') fprintf (FILE, "ccr");                \
  252.   else if (GET_CODE (X) == REG)                        \
  253.     fprintf (FILE, "%s", reg_names[REGNO (X)]);                \
  254.   else if (GET_CODE (X) == MEM)                        \
  255.     output_address (XEXP (X, 0));                    \
  256.   else if (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) == SFmode)    \
  257.     { union { double d; int i[2]; } u;                    \
  258.       union { float f; int i; } u1;                    \
  259.       u.i[0] = CONST_DOUBLE_LOW (X); u.i[1] = CONST_DOUBLE_HIGH (X);    \
  260.       u1.f = u.d;                            \
  261.       if (CODE == 'f')                            \
  262.         fprintf (FILE, "#0f%.9e", u1.f);                \
  263.       else                                \
  264.         fprintf (FILE, "#0x%x", u1.i); }                \
  265.   else if (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) != DImode)    \
  266.     { union { double d; int i[2]; } u;                    \
  267.       u.i[0] = CONST_DOUBLE_LOW (X); u.i[1] = CONST_DOUBLE_HIGH (X);    \
  268.       fprintf (FILE, "#0d%.20e", u.d); }                \
  269.   else if (CODE == 'b') output_addr_const (FILE, X);            \
  270.   else { putc ('#', FILE); output_addr_const (FILE, X); }}
  271.  
  272. #define PRINT_OPERAND_ADDRESS(FILE, ADDR)  \
  273. { register rtx reg1, reg2, breg, ireg;                    \
  274.   register rtx addr = ADDR;                        \
  275.   rtx offset;                                \
  276.   switch (GET_CODE (addr))                        \
  277.     {                                    \
  278.     case REG:                                \
  279.       fprintf (FILE, "(%s)", reg_names[REGNO (addr)]);            \
  280.       break;                                \
  281.     case PRE_DEC:                            \
  282.       fprintf (FILE, "-(%s)", reg_names[REGNO (XEXP (addr, 0))]);    \
  283.       break;                                \
  284.     case POST_INC:                            \
  285.       fprintf (FILE, "(%s)+", reg_names[REGNO (XEXP (addr, 0))]);    \
  286.       break;                                \
  287.     case PLUS:                                \
  288.       reg1 = 0;    reg2 = 0;                        \
  289.       ireg = 0;    breg = 0;                        \
  290.       offset = 0;                            \
  291.       if (CONSTANT_ADDRESS_P (XEXP (addr, 0)))                \
  292.     {                                \
  293.       offset = XEXP (addr, 0);                    \
  294.       addr = XEXP (addr, 1);                    \
  295.     }                                \
  296.       else if (CONSTANT_ADDRESS_P (XEXP (addr, 1)))            \
  297.     {                                \
  298.       offset = XEXP (addr, 1);                    \
  299.       addr = XEXP (addr, 0);                    \
  300.     }                                \
  301.       if (GET_CODE (addr) != PLUS) ;                    \
  302.       else if (GET_CODE (XEXP (addr, 0)) == SIGN_EXTEND)        \
  303.     {                                \
  304.       reg1 = XEXP (addr, 0);                    \
  305.       addr = XEXP (addr, 1);                    \
  306.     }                                \
  307.       else if (GET_CODE (XEXP (addr, 1)) == SIGN_EXTEND)        \
  308.     {                                \
  309.       reg1 = XEXP (addr, 1);                    \
  310.       addr = XEXP (addr, 0);                    \
  311.     }                                \
  312.       else if (GET_CODE (XEXP (addr, 0)) == MULT)            \
  313.     {                                \
  314.       reg1 = XEXP (addr, 0);                    \
  315.       addr = XEXP (addr, 1);                    \
  316.     }                                \
  317.       else if (GET_CODE (XEXP (addr, 1)) == MULT)            \
  318.     {                                \
  319.       reg1 = XEXP (addr, 1);                    \
  320.       addr = XEXP (addr, 0);                    \
  321.     }                                \
  322.       else if (GET_CODE (XEXP (addr, 0)) == REG)            \
  323.     {                                \
  324.       reg1 = XEXP (addr, 0);                    \
  325.       addr = XEXP (addr, 1);                    \
  326.     }                                \
  327.       else if (GET_CODE (XEXP (addr, 1)) == REG)            \
  328.     {                                \
  329.       reg1 = XEXP (addr, 1);                    \
  330.       addr = XEXP (addr, 0);                    \
  331.     }                                \
  332.       if (GET_CODE (addr) == REG || GET_CODE (addr) == MULT        \
  333.       || GET_CODE (addr) == SIGN_EXTEND)                \
  334.     { if (reg1 == 0) reg1 = addr; else reg2 = addr; addr = 0; }    \
  335.       if (offset != 0) { if (addr != 0) abort (); addr = offset; }    \
  336.       if ((reg1 && (GET_CODE (reg1) == SIGN_EXTEND            \
  337.             || GET_CODE (reg1) == MULT))            \
  338.       || (reg2 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg2))))        \
  339.     { breg = reg2; ireg = reg1; }                    \
  340.       else if (reg1 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg1)))        \
  341.     { breg = reg1; ireg = reg2; }                    \
  342.       if (ireg != 0 && breg == 0 && GET_CODE (addr) == LABEL_REF)    \
  343.         { int scale = 1;                        \
  344.       if (GET_CODE (ireg) == MULT)                    \
  345.         { scale = INTVAL (XEXP (ireg, 1));                \
  346.           ireg = XEXP (ireg, 0); }                    \
  347.       if (GET_CODE (ireg) == SIGN_EXTEND)                \
  348.         fprintf (FILE, "(L%d.b,pc,%s.w",                \
  349.              CODE_LABEL_NUMBER (XEXP (addr, 0)),        \
  350.              reg_names[REGNO (XEXP (ireg, 0))]);         \
  351.       else                                \
  352.         fprintf (FILE, "(L%d.b,pc,%s.l",                \
  353.              CODE_LABEL_NUMBER (XEXP (addr, 0)),        \
  354.              reg_names[REGNO (ireg)]);                \
  355.       if (scale != 1) fprintf (FILE, "*%d", scale);            \
  356.       putc (')', FILE);                        \
  357.       break; }                            \
  358.       if (breg != 0 && ireg == 0 && GET_CODE (addr) == LABEL_REF)    \
  359.         { fprintf (FILE, "(L%d.b,pc,%s.l",                \
  360.            CODE_LABEL_NUMBER (XEXP (addr, 0)),            \
  361.            reg_names[REGNO (breg)]);                \
  362.       putc (')', FILE);                        \
  363.       break; }                            \
  364.       if (ireg != 0 || breg != 0)                    \
  365.     { int scale = 1;                        \
  366.       if (breg == 0)                        \
  367.         abort ();                            \
  368.       if (addr && GET_CODE (addr) == LABEL_REF) abort ();        \
  369.       fprintf (FILE, "(");                        \
  370.       if (addr != 0) {                        \
  371.         output_addr_const (FILE, addr);                \
  372.         putc (',', FILE); }                        \
  373.       fprintf (FILE, "%s", reg_names[REGNO (breg)]);        \
  374.       if (ireg != 0)                        \
  375.         putc (',', FILE);                        \
  376.       if (ireg != 0 && GET_CODE (ireg) == MULT)            \
  377.         { scale = INTVAL (XEXP (ireg, 1));                \
  378.           ireg = XEXP (ireg, 0); }                    \
  379.       if (ireg != 0 && GET_CODE (ireg) == SIGN_EXTEND)        \
  380.         fprintf (FILE, "%s.w", reg_names[REGNO (XEXP (ireg, 0))]);    \
  381.       else if (ireg != 0)                        \
  382.         fprintf (FILE, "%s.l", reg_names[REGNO (ireg)]);        \
  383.       if (scale != 1) fprintf (FILE, "*%d", scale);            \
  384.       putc (')', FILE);                        \
  385.       break;                            \
  386.     }                                \
  387.       else if (reg1 != 0 && GET_CODE (addr) == LABEL_REF)        \
  388.     { fprintf (FILE, "(L%d.b,pc,%s:l)",                \
  389.            CODE_LABEL_NUMBER (XEXP (addr, 0)),            \
  390.            reg_names[REGNO (reg1)]);                \
  391.       break; }                            \
  392.     default:                                \
  393.       if (GET_CODE (addr) == CONST_INT                    \
  394.       && INTVAL (addr) < 0x8000                    \
  395.       && INTVAL (addr) >= -0x8000)                    \
  396.     fprintf (FILE, "%d.w", INTVAL (addr));                \
  397.       else                                \
  398.         output_addr_const (FILE, addr);                    \
  399.     }}
  400.  
  401. #else /* Using GAS, which uses the MIT assembler syntax, like a Sun.  */
  402.  
  403. #define FUNCTION_PROFILER(FILE, LABEL_NO) \
  404.    fprintf (FILE, "\tmovl #LP%d,d0\n\tjsr mcount\n", (LABEL_NO));
  405.  
  406. #endif /* MOTOROLA */
  407.